package com.luoye.lj.aop;

import com.luoye.lj.platform.dao.IAuthServiceDao;
import com.luoye.lj.platform.dao.IManageMenuDao;
import com.luoye.lj.platform.model.UserModel;
import com.luoye.lj.platform.model.domain.AuthInfo;
import com.luoye.lj.platform.model.domain.muser.MUserDetail;
import com.luoye.lj.platform.pojo.dbo.ManageMenuDbo;
import com.luoye.lj.platform.pojo.dbo.ManageMenuDboCollection;
import com.luoye.lj.platform.pojo.dbo.ManageMenuDboSearchCondition;
import com.luoye.lj.platform.pojo.vo.MenuGroupVo;
import com.luoye.lj.util.converter.PojoConvertUtil;
import com.luoye.lj.util.mvc.annotation.OperateLog;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.bind.annotation.RequestMapping;

import java.lang.reflect.Method;
import java.util.*;

@Component
@Aspect
public class SystemPropertiesShowAspect {
    private static Logger logger = LoggerFactory.getLogger(SystemPropertiesShowAspect.class);

    @Value("${app.title}")
    String appTitle;

    @Autowired
    private IManageMenuDao manageMenuDao;
    @Autowired
    private IAuthServiceDao authServiceDao;

    @Before("execution(public * com.luoye.lj.platform.controller.*.*(..))" +
            "|| execution(public * com.luoye.lj.controller.*.*(..))")
    public void addShowProperties(JoinPoint joinPoint) {
        Object target=joinPoint.getTarget();
        MethodSignature sign = (MethodSignature) joinPoint.getSignature();
        Method method = sign.getMethod();
        Object[] args = joinPoint.getArgs();
        logger.debug("method->"+method);
        logger.debug("target->"+joinPoint.getTarget().toString());

        for(Object arg:args){
            //logger.info("arg->"+arg);
            if(arg instanceof Model){
                logger.info("is model");
                ((Model)arg).addAttribute("appTitle",appTitle);
                if (SecurityContextHolder.getContext().getAuthentication().getPrincipal() instanceof UserModel) {
                    UserModel userDetails = (UserModel) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
                    MUserDetail mUserDetail = userDetails.getmUserDetail();
                    Model a=(Model)arg;
                    a.addAttribute("managerName",mUserDetail.getUsername());

                    //查出所有权限
                    List<AuthInfo> allAuths = authServiceDao.getAll();

                    //查出所有的菜单
                    ManageMenuDboSearchCondition manageMenuDboSearchCondition=new ManageMenuDboSearchCondition();
                    manageMenuDboSearchCondition.setMax(Integer.MAX_VALUE);
                    ManageMenuDboCollection manageMenuDboCollection = manageMenuDao.searchByCondition(manageMenuDboSearchCondition);
                    logger.debug("manageMenuDboCollection->"+manageMenuDboCollection);
                    //分组
                    Map<Long, MenuGroupVo> map=new HashMap<>();
                    if(manageMenuDboCollection.getTotalCount()>0){
                        //先找出所有一级
                        for(ManageMenuDbo manageMenuDbo:manageMenuDboCollection.getEntityList()){
                            if(manageMenuDbo.getParentId()==0){
                                MenuGroupVo menuGroupVo= PojoConvertUtil.convertPojo(manageMenuDbo,MenuGroupVo.class);
                                menuGroupVo.setChildren(new ArrayList<>());
                                menuGroupVo.setHasAuthority(checkAuth(allAuths,menuGroupVo));
                                map.put(Long.valueOf(menuGroupVo.getId()),menuGroupVo);
                            }
                        }
                        //添加二级
                        for(ManageMenuDbo manageMenuDbo:manageMenuDboCollection.getEntityList()){
                            MenuGroupVo menuGroupVo=map.get(Long.valueOf(manageMenuDbo.getParentId()));
                            logger.debug("menu->"+menuGroupVo);
                            if(menuGroupVo!=null) {
                                MenuGroupVo menuGroupVoChild= PojoConvertUtil.convertPojo(manageMenuDbo,MenuGroupVo.class);
                                if(checkAuth(allAuths, menuGroupVoChild)) {
                                    menuGroupVoChild.setHasAuthority(checkAuth(allAuths, menuGroupVoChild));
                                    menuGroupVo.getChildren().add(menuGroupVoChild);
                                    if (checkActive(target, method, menuGroupVoChild)) {
                                        menuGroupVo.setExpansion(true);
                                    }
                                }
                            }
                        }
                        logger.debug("menus->"+map);
                    }
                    a.addAttribute("manageMenus",map.values());
                }
                break;
            }
        }
        //logger.info("args->"+args.length);
    }
    private boolean checkActive(Object controller,Method method,MenuGroupVo menuGroupVo){
        if (controller.getClass().isAnnotationPresent(RequestMapping.class)) {
            RequestMapping requestMapping = controller.getClass().getAnnotation(RequestMapping.class);
            String[] paths = requestMapping.value();
            String path="";
            for(String p:paths){
                path+=p;
            }
            //将方法上的路径也加上
            if (method.isAnnotationPresent(RequestMapping.class)) {
                requestMapping = method.getAnnotation(RequestMapping.class);
                paths = requestMapping.value();
                for (String p : paths) {
                    path += p;
                }
            }
            logger.debug("path->"+path);
            if(path.equals(menuGroupVo.getMenuUrl())){
                return true;
            }
        }
        return false;
    }
    private boolean checkAuth(List<AuthInfo> allAuths,MenuGroupVo menuGroupVo){
        if (SecurityContextHolder.getContext().getAuthentication().getPrincipal() instanceof UserModel) {
            UserModel userDetails = (UserModel) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
            Collection<GrantedAuthority> authoritiesT = userDetails.getAuthorities();
            List<String> authorities=new ArrayList<>();
            for(GrantedAuthority grantedAuthority:authoritiesT){
                authorities.add(grantedAuthority.getAuthority());
            }
            //根据路劲找到对应权限
            List<String> auths=new ArrayList<>();
            AntPathMatcher antPathMatcher=new AntPathMatcher();
            for(AuthInfo authInfo:allAuths){
                if(antPathMatcher.match(authInfo.getPatterns(),menuGroupVo.getMenuUrl())){
                    auths.add(authInfo.getAuthname());
                }
            }
            if(auths.size()==0){
                return true;
            }
            for(String auth:auths){
                if(authorities.contains(auth)){
                    return true;
                }
            }
        }
        return false;
    }
}
